package com.glorystone.ins.shiro;

import com.glorystone.ins.common.constants.Constants;
import com.glorystone.ins.domain.SysUser;
import com.glorystone.ins.service.ISysUserService;

import com.google.common.collect.Lists;

import redis.clients.jedis.Jedis;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import java.util.List;

public class UserRealm extends AuthorizingRealm {

    private static final Logger log = LoggerFactory.getLogger("UserRealm");

    @Autowired
    private ISysUserService sysUserService;
    @Value("${errorTimes}")
    private Integer errorTimes;
    @Value("${redis.host}")
    private String redisHost;
    @Value("${redis.port}")
    private Integer redisPort;
    @Value("${redis.timeout}")
    private Integer timeOut;


    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        SysUser user = (SysUser) principals.getPrimaryPrincipal();

        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        if(user == null){
            //添加用户的角色以及 权限
            authorizationInfo.setRoles(sysUserService.getRoleNameSetByUsername(user.getJobNumber()));
            log.info("已经添加用户的角色~~~");
            authorizationInfo.setStringPermissions(sysUserService.getAuthSetByUsername(user.getJobNumber()));
            log.info("已经添加用户的权限~~~");
        }else{
            authorizationInfo.setRoles(user.getRoles());
            authorizationInfo.setStringPermissions(user.getStringPermissions());
        }
        return authorizationInfo;
    }

    @SuppressWarnings("resource")
	@Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
    	CaptchaUsernamePasswordToken theToken = (CaptchaUsernamePasswordToken) token;

        String inputCaptcha = theToken.getCaptcha();
        String captcha = (String) SecurityUtils.getSubject().getSession().getAttribute(com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY);

        if (!captcha.equalsIgnoreCase(inputCaptcha)) {
            throw new IncorrectCaptchaException("验证码错误");
        }
        
        //对用户信息进行验证 
        String jobNumber = (String) token.getPrincipal();
       if(jobNumber!=null){
        	Jedis jedis = new Jedis(redisHost,redisPort,timeOut);
        	String Uservalue = jedis.get(jobNumber+"Count");
        	if(Uservalue!=null){
        		if(Integer.parseInt(Uservalue)==errorTimes){
        			throw new IncorrectCredentialsException("该账户已被锁定,请稍后再登录");
        		}
        	}
        	jedis.close();
        }
        SysUser user = sysUserService.getUserByUserName(jobNumber);
        if (user == null) {
            throw new UnknownAccountException("暂无此账户");//没找到帐号
        }
        if (Constants.ONE == user.getDelFlag()) {
            throw new LockedAccountException(); //帐号锁定
        }        
        if(user.getStatus()==1){
        	throw new DisabledException("该账户暂不可用");
        }
        if(user.getRoleDelFlag()==1){
            throw new DisabledException("该账户对应角色已删除");
        }
        if(user.getRoleStatus()==1){
            throw new DisabledException("该账户对应角色已禁用");
        }
        int level = user.getUserLevel();
        List<String> ids = Lists.newArrayList();
        ids.add(""+user.getTid());
        if(0 == level){
            user.setUserLevel(3);
        }else if(2 == level){
            ids =  sysUserService.getIdsByOfficeId(user.getOfficeId());

        }
        user.setUserIds(ids);
          
        //交给AuthenticatingRealm使用CredentialsMatcher进行密码匹配 
        //这里传入的密码是密文的
        //这里传入盐会加密后和上面的密码进行比对
        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
                user, //用户名
                user.getPassword(), //密码
                ByteSource.Util.bytes(user.getCredentialsSalt()),
                getName()
        );
        
        return authenticationInfo;
    }

}